package main.java.com.healthy.controller;
import main.java.com.healthy.entity.DietRecord;
import main.java.com.healthy.entity.Food;
import main.java.com.healthy.entity.NutritionGoal;
import main.java.com.healthy.entity.User;
import main.java.com.healthy.service.DietRecordService;
import main.java.com.healthy.service.FoodService;
import main.java.com.healthy.service.NutritionAnalysisService;
import main.java.com.healthy.service.NutritionGoalService;
import main.java.com.healthy.service.impl.DietRecordServiceImpl;
import main.java.com.healthy.service.impl.FoodServiceImpl;
import main.java.com.healthy.service.impl.NutritionAnalysisServiceImpl;
import main.java.com.healthy.service.impl.NutritionGoalServiceImpl;
import main.java.com.healthy.util.DateUtil;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

/**
 * 饮食记录控制器
 * 对应功能模块：饮食记录与追踪模块、营养分析与评估模块
 */
public class DietController {
    private DietRecordService dietService;
    private FoodService foodService;
    private NutritionGoalService goalService;
    private NutritionAnalysisService analysisService;
    private Scanner scanner;

    public DietController() {
        this.dietService = new DietRecordServiceImpl();
        this.foodService = new FoodServiceImpl();
        this.goalService = new NutritionGoalServiceImpl();
        this.analysisService = new NutritionAnalysisServiceImpl();
        this.scanner = new Scanner(System.in);
    }

    /**
     * 管理饮食记录
     */
    public void manageDietRecords(User user) {
        while (true) {
            System.out.println("\n=== 饮食记录管理 ===");
            System.out.println("1. 添加饮食记录");
            System.out.println("2. 查看今日记录");
            System.out.println("3. 查看历史记录");
            System.out.println("4. 修改饮食记录");
            System.out.println("5. 删除饮食记录");
            System.out.println("6. 今日营养分析");
            System.out.println("7. 返回主菜单");
            System.out.print("请选择: ");

            String choice = scanner.nextLine().trim();

            switch (choice) {
                case "1":
                    addDietRecord(user);
                    break;
                case "2":
                    viewTodayRecords(user);
                    break;
                case "3":
                    viewHistoryRecords(user);
                    break;
                case "4":
                    updateDietRecord(user);
                    break;
                case "5":
                    deleteDietRecord(user);
                    break;
                case "6":
                    analyzeTodayNutrition(user);
                    break;
                case "7":
                    return;
                default:
                    System.out.println("无效选择，请重新输入！");
            }
        }
    }

    /**
     * 添加饮食记录
     */
    private void addDietRecord(User user) {
        System.out.println("\n=== 添加饮食记录 ===");

        // 选择日期
        LocalDate recordDate;
        System.out.print("请输入记录日期(YYYY-MM-DD) [今天直接回车]: ");
        String dateInput = scanner.nextLine().trim();
        if (dateInput.isEmpty()) {
            recordDate = LocalDate.now();
        } else {
            try {
                recordDate = LocalDate.parse(dateInput);
            } catch (Exception e) {
                System.out.println("日期格式错误，使用今天日期");
                recordDate = LocalDate.now();
            }
        }

        // 选择餐次
        System.out.println("请选择餐次:");
        System.out.println("1. 早餐");
        System.out.println("2. 上午加餐");
        System.out.println("3. 午餐");
        System.out.println("4. 下午加餐");
        System.out.println("5. 晚餐");
        System.out.println("6. 夜宵");
        System.out.print("请选择(1-6): ");

        String mealType;
        int mealChoice = getValidIntInput(1, 6);
        switch (mealChoice) {
            case 1: mealType = "早餐"; break;
            case 2: mealType = "上午加餐"; break;
            case 3: mealType = "午餐"; break;
            case 4: mealType = "下午加餐"; break;
            case 5: mealType = "晚餐"; break;
            case 6: mealType = "夜宵"; break;
            default: mealType = "午餐";
        }

        // 搜索食物
        System.out.print("请输入食物名称关键字: ");
        String keyword = scanner.nextLine().trim();

        List<Food> foods = foodService.searchFoods(keyword);
        if (foods.isEmpty()) {
            System.out.println("没有找到匹配的食物！");
            return;
        }

        System.out.println("找到 " + foods.size() + " 个匹配的食物:");
        for (int i = 0; i < foods.size(); i++) {
            Food food = foods.get(i);
            System.out.printf("%d. %s (%.0f千卡/100g)%n",
                    i + 1, food.getFoodName(), food.getCalories());
        }

        System.out.print("请选择食物编号: ");
        int foodChoice = getValidIntInput(1, foods.size());
        Food selectedFood = foods.get(foodChoice - 1);

        // 输入重量
        System.out.print("请输入食物重量(g): ");
        double weight = getValidDoubleInput(1, 5000);

        // 创建记录
        DietRecord record = new DietRecord();
        record.setUserId(user.getUserId());
        record.setFoodId(selectedFood.getFoodId());
        record.setFoodName(selectedFood.getFoodName());
        record.setFoodWeight(weight);
        record.setRecordDate(recordDate);
        record.setMealType(mealType);
        record.updateNutrition(selectedFood);

        if (dietService.addDietRecord(record)) {
            System.out.println("饮食记录添加成功！");
            System.out.println("摄入营养:");
            System.out.println("  热量: " + String.format("%.1f", record.getCalories()) + " 千卡");
            System.out.println("  碳水: " + String.format("%.1f", record.getCarbohydrates()) + " g");
            System.out.println("  蛋白质: " + String.format("%.1f", record.getProtein()) + " g");
            System.out.println("  脂肪: " + String.format("%.1f", record.getFat()) + " g");
        } else {
            System.out.println("饮食记录添加失败！");
        }
    }

    /**
     * 查看今日记录
     */
    private void viewTodayRecords(User user) {
        System.out.println("\n=== 今日饮食记录 ===");

        LocalDate today = LocalDate.now();
        List<DietRecord> records = dietService.getDailyRecords(user.getUserId(), today);

        if (records.isEmpty()) {
            System.out.println("今天还没有饮食记录！");
            return;
        }

        displayDailyRecords(records, today);

        // 显示今日营养汇总
        Map<String, Double> nutrition = dietService.calculateDailyNutrition(user.getUserId(), today);
        displayNutritionSummary(nutrition, "今日");

        System.out.println("\n按回车键返回...");
        scanner.nextLine();
    }

    /**
     * 查看历史记录
     */
    private void viewHistoryRecords(User user) {
        System.out.println("\n=== 历史饮食记录 ===");

        System.out.print("请输入开始日期(YYYY-MM-DD): ");
        String startInput = scanner.nextLine().trim();
        System.out.print("请输入结束日期(YYYY-MM-DD): ");
        String endInput = scanner.nextLine().trim();

        LocalDate startDate, endDate;
        try {
            startDate = LocalDate.parse(startInput);
            endDate = LocalDate.parse(endInput);
        } catch (Exception e) {
            System.out.println("日期格式错误！");
            return;
        }

        if (startDate.isAfter(endDate)) {
            System.out.println("开始日期不能晚于结束日期！");
            return;
        }

        List<DietRecord> records = dietService.getRecordsByUserAndDateRange(
                user.getUserId(), startDate, endDate);

        if (records.isEmpty()) {
            System.out.println("指定时间段内没有饮食记录！");
            return;
        }

        // 按日期分组显示
        Map<LocalDate, List<DietRecord>> recordsByDate =
                records.stream().collect(java.util.stream.Collectors.groupingBy(DietRecord::getRecordDate));

        for (LocalDate date : recordsByDate.keySet().stream().sorted().collect(java.util.stream.Collectors.toList())) {
            System.out.println("\n=== " + DateUtil.formatDate(date) + " ===");
            displayDailyRecords(recordsByDate.get(date), date);

            Map<String, Double> nutrition = dietService.calculateDailyNutrition(user.getUserId(), date);
            displayNutritionSummary(nutrition, "当日");
            System.out.println("----------------------");
        }

        // 显示时间段汇总
        Map<String, Double> summary = dietService.calculateNutritionSummary(
                user.getUserId(), startDate, endDate);
        displayPeriodSummary(summary, startDate, endDate);

        System.out.println("\n按回车键返回...");
        scanner.nextLine();
    }

    /**
     * 修改饮食记录
     */
    private void updateDietRecord(User user) {
        System.out.println("\n=== 修改饮食记录 ===");

        // 先显示最近的记录
        List<LocalDate> recentDates = dietService.getRecentRecordDates(user.getUserId(), 7);
        if (recentDates.isEmpty()) {
            System.out.println("没有找到最近的饮食记录！");
            return;
        }

        System.out.println("最近有记录的日期:");
        for (int i = 0; i < recentDates.size(); i++) {
            System.out.println((i + 1) + ". " + DateUtil.formatDate(recentDates.get(i)));
        }

        System.out.print("请选择日期编号: ");
        int dateChoice = getValidIntInput(1, recentDates.size());
        LocalDate selectedDate = recentDates.get(dateChoice - 1);

        List<DietRecord> records = dietService.getDailyRecords(user.getUserId(), selectedDate);
        displayDailyRecords(records, selectedDate);

        System.out.print("请选择要修改的记录编号: ");
        int recordChoice = getValidIntInput(1, records.size());
        DietRecord record = records.get(recordChoice - 1);

        System.out.println("当前记录信息:");
        System.out.println("食物: " + record.getFoodName());
        System.out.println("重量: " + record.getFoodWeight() + " g");
        System.out.println("餐次: " + record.getMealType());

        System.out.println("\n请输入新的信息（直接回车保持原值）:");

        System.out.print("食物重量(g) [" + record.getFoodWeight() + "]: ");
        String weightInput = scanner.nextLine().trim();
        if (!weightInput.isEmpty()) {
            double newWeight = Double.parseDouble(weightInput);
            record.setFoodWeight(newWeight);

            // 重新计算营养
            Food food = foodService.getFoodById(record.getFoodId());
            if (food != null) {
                record.updateNutrition(food);
            }
        }

        System.out.println("请选择餐次:");
        System.out.println("1. 早餐");
        System.out.println("2. 上午加餐");
        System.out.println("3. 午餐");
        System.out.println("4. 下午加餐");
        System.out.println("5. 晚餐");
        System.out.println("6. 夜宵");
        System.out.print("请选择(1-6) [当前: " + getMealTypeCode(record.getMealType()) + "]: ");

        String mealInput = scanner.nextLine().trim();
        if (!mealInput.isEmpty()) {
            int mealChoice = Integer.parseInt(mealInput);
            if (mealChoice >= 1 && mealChoice <= 6) {
                switch (mealChoice) {
                    case 1: record.setMealType("早餐"); break;
                    case 2: record.setMealType("上午加餐"); break;
                    case 3: record.setMealType("午餐"); break;
                    case 4: record.setMealType("下午加餐"); break;
                    case 5: record.setMealType("晚餐"); break;
                    case 6: record.setMealType("夜宵"); break;
                }
            }
        }

        if (dietService.updateDietRecord(record)) {
            System.out.println("饮食记录修改成功！");
        } else {
            System.out.println("饮食记录修改失败！");
        }
    }

    /**
     * 删除饮食记录
     */
    private void deleteDietRecord(User user) {
        System.out.println("\n=== 删除饮食记录 ===");

        // 显示最近的记录（简化实现）
        System.out.print("请输入记录日期(YYYY-MM-DD): ");
        String dateInput = scanner.nextLine().trim();

        LocalDate recordDate;
        try {
            recordDate = LocalDate.parse(dateInput);
        } catch (Exception e) {
            System.out.println("日期格式错误！");
            return;
        }

        List<DietRecord> records = dietService.getDailyRecords(user.getUserId(), recordDate);
        if (records.isEmpty()) {
            System.out.println("指定日期没有饮食记录！");
            return;
        }

        displayDailyRecords(records, recordDate);

        System.out.print("请选择要删除的记录编号: ");
        int recordChoice = getValidIntInput(1, records.size());
        DietRecord record = records.get(recordChoice - 1);

        System.out.println("将要删除的记录:");
        System.out.println("日期: " + DateUtil.formatDate(record.getRecordDate()));
        System.out.println("餐次: " + record.getMealType());
        System.out.println("食物: " + record.getFoodName());
        System.out.println("重量: " + record.getFoodWeight() + " g");

        System.out.print("确认删除？(y/n): ");
        String confirm = scanner.nextLine().trim().toLowerCase();

        if ("y".equals(confirm) || "yes".equals(confirm)) {
            if (dietService.deleteDietRecord(record.getRecordId())) {
                System.out.println("饮食记录删除成功！");
            } else {
                System.out.println("饮食记录删除失败！");
            }
        } else {
            System.out.println("取消删除操作。");
        }
    }

    /**
     * 分析今日营养
     */
    private void analyzeTodayNutrition(User user) {
        System.out.println("\n=== 今日营养分析 ===");

        LocalDate today = LocalDate.now();
        Map<String, Object> analysis = analysisService.analyzeDailyNutrition(user.getUserId(), today);

        // 显示摄入情况
        @SuppressWarnings("unchecked")
        Map<String, Double> intake = (Map<String, Double>) analysis.get("intake");
        System.out.println("今日摄入:");
        System.out.println("  热量: " + String.format("%.1f", intake.get("calories")) + " 千卡");
        System.out.println("  碳水: " + String.format("%.1f", intake.get("carbohydrates")) + " g");
        System.out.println("  蛋白质: " + String.format("%.1f", intake.get("protein")) + " g");
        System.out.println("  脂肪: " + String.format("%.1f", intake.get("fat")) + " g");

        // 获取营养目标
        NutritionGoal goal = goalService.getNutritionGoal(user.getUserId());
        if (goal != null) {
            System.out.println("\n与目标对比:");
            displayGoalComparison(intake, goal);
        }

        // 显示分析结果
        @SuppressWarnings("unchecked")
        Map<String, String> assessment = (Map<String, String>) analysis.get("assessment");
        System.out.println("\n营养评估:");
        for (Map.Entry<String, String> entry : assessment.entrySet()) {
            System.out.println("  " + entry.getKey() + ": " + entry.getValue());
        }

        System.out.println("\n按回车键返回...");
        scanner.nextLine();
    }

    /**
     * 显示每日记录
     */
    private void displayDailyRecords(List<DietRecord> records, LocalDate date) {
        System.out.println("日期: " + DateUtil.formatDate(date));
        System.out.printf("%-4s %-8s %-20s %-8s %-8s %-8s %-8s %-8s%n",
                "序号", "餐次", "食物名称", "重量", "热量", "碳水", "蛋白质", "脂肪");
        System.out.println("----------------------------------------------------------------------------------------");

        double totalCalories = 0, totalCarbs = 0, totalProtein = 0, totalFat = 0;

        for (int i = 0; i < records.size(); i++) {
            DietRecord record = records.get(i);
            System.out.printf("%-4d %-8s %-20s %-8.0f %-8.1f %-8.1f %-8.1f %-8.1f%n",
                    i + 1,
                    record.getMealType(),
                    record.getFoodName(),
                    record.getFoodWeight(),
                    record.getCalories(),
                    record.getCarbohydrates(),
                    record.getProtein(),
                    record.getFat());

            totalCalories += record.getCalories();
            totalCarbs += record.getCarbohydrates();
            totalProtein += record.getProtein();
            totalFat += record.getFat();
        }

        System.out.println("----------------------------------------------------------------------------------------");
        System.out.printf("%-32s %-8s %-8.1f %-8.1f %-8.1f %-8.1f%n",
                "总计", "", totalCalories, totalCarbs, totalProtein, totalFat);
    }

    /**
     * 显示营养汇总
     */
    private void displayNutritionSummary(Map<String, Double> nutrition, String period) {
        System.out.println("\n" + period + "营养汇总:");
        System.out.println("  总热量: " + String.format("%.1f", nutrition.get("calories")) + " 千卡");
        System.out.println("  总碳水: " + String.format("%.1f", nutrition.get("carbohydrates")) + " g");
        System.out.println("  总蛋白质: " + String.format("%.1f", nutrition.get("protein")) + " g");
        System.out.println("  总脂肪: " + String.format("%.1f", nutrition.get("fat")) + " g");
        if (nutrition.containsKey("fiber")) {
            System.out.println("  总膳食纤维: " + String.format("%.1f", nutrition.get("fiber")) + " g");
        }
    }

    /**
     * 显示时间段汇总
     */
    private void displayPeriodSummary(Map<String, Double> summary, LocalDate startDate, LocalDate endDate) {
        long days = startDate.until(endDate).getDays() + 1;
        System.out.println("\n=== 时间段汇总 (" + days + "天) ===");
        System.out.println("  总热量: " + String.format("%.0f", summary.get("totalCalories")) + " 千卡");
        System.out.println("  平均每日热量: " + String.format("%.0f", summary.get("averageCalories")) + " 千卡");
        System.out.println("  总碳水: " + String.format("%.0f", summary.get("totalCarbs")) + " g");
        System.out.println("  平均每日碳水: " + String.format("%.0f", summary.get("averageCarbs")) + " g");
        System.out.println("  总蛋白质: " + String.format("%.0f", summary.get("totalProtein")) + " g");
        System.out.println("  平均每日蛋白质: " + String.format("%.0f", summary.get("averageProtein")) + " g");
        System.out.println("  总脂肪: " + String.format("%.0f", summary.get("totalFat")) + " g");
        System.out.println("  平均每日脂肪: " + String.format("%.0f", summary.get("averageFat")) + " g");
    }

    /**
     * 显示目标对比
     */
    private void displayGoalComparison(Map<String, Double> intake, NutritionGoal goal) {
        double caloriePercent = (intake.get("calories") / goal.getDailyCalorieGoal()) * 100;
        double carbsPercent = (intake.get("carbohydrates") / goal.getDailyCarbsGoal()) * 100;
        double proteinPercent = (intake.get("protein") / goal.getDailyProteinGoal()) * 100;
        double fatPercent = (intake.get("fat") / goal.getDailyFatGoal()) * 100;

        System.out.printf("  热量: %.1f / %.0f (%.1f%%)%n",
                intake.get("calories"), goal.getDailyCalorieGoal(), caloriePercent);
        System.out.printf("  碳水: %.1f / %.0f (%.1f%%)%n",
                intake.get("carbohydrates"), goal.getDailyCarbsGoal(), carbsPercent);
        System.out.printf("  蛋白质: %.1f / %.0f (%.1f%%)%n",
                intake.get("protein"), goal.getDailyProteinGoal(), proteinPercent);
        System.out.printf("  脂肪: %.1f / %.0f (%.1f%%)%n",
                intake.get("fat"), goal.getDailyFatGoal(), fatPercent);

        // 简单评估
        System.out.print("  热量状态: ");
        if (caloriePercent < 80) {
            System.out.println("不足");
        } else if (caloriePercent > 120) {
            System.out.println("超标");
        } else {
            System.out.println("良好");
        }
    }

    // 辅助方法
    private int getMealTypeCode(String mealType) {
        switch (mealType) {
            case "早餐": return 1;
            case "上午加餐": return 2;
            case "午餐": return 3;
            case "下午加餐": return 4;
            case "晚餐": return 5;
            case "夜宵": return 6;
            default: return 3;
        }
    }

    private int getValidIntInput(int min, int max) {
        while (true) {
            try {
                String input = scanner.nextLine().trim();
                int value = Integer.parseInt(input);
                if (value >= min && value <= max) {
                    return value;
                } else {
                    System.out.print("输入值应在 " + min + " 到 " + max + " 之间，请重新输入: ");
                }
            } catch (NumberFormatException e) {
                System.out.print("请输入有效的整数: ");
            }
        }
    }

    private double getValidDoubleInput(double min, double max) {
        while (true) {
            try {
                String input = scanner.nextLine().trim();
                double value = Double.parseDouble(input);
                if (value >= min && value <= max) {
                    return value;
                } else {
                    System.out.print("输入值应在 " + min + " 到 " + max + " 之间，请重新输入: ");
                }
            } catch (NumberFormatException e) {
                System.out.print("请输入有效的数字: ");
            }
        }
    }
}